#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include "cargarImagenes.h"
#include "resizeImagenes.h"
#include "algoritmos.h"
#include <time.h>

using namespace std;
double psnr;
FILE * imagen;
FILE * imagenNueva;

void sacarRuido(FILE * imagenAFiltrar, float lambda)
{
    vector<float> x;
    pair<Matriz, vector<float> > tuplaCargada;

    imagenNueva = fopen("./ImagenFiltrada.pgm", "w+");

    tuplaCargada = crearAyB(imagenAFiltrar,lambda,imagenNueva);

    cout << "Empezo Gauss" << endl;
    x = gauss(tuplaCargada.first, tuplaCargada.second);
    cout << "Termino Gauss" << endl << endl;

    ///Meto los pixeles en el archivo.
    cout << "Creando la imagen filtrada" << endl << endl;
    for (int i=0; i<(int)x.size(); i++)
    {
//        cout << x[i] << endl;
        fputc((int)x[i], imagenNueva);
    }
}

double calcPSNR(FILE * imagen, FILE * imagenNueva)
{
    Foto fotoImagen;
    fotoImagen.guardarImagen(imagen);

    Foto fotoImagenNueva;
    fotoImagenNueva.guardarImagen(imagenNueva);

    return PSNR(fotoImagen,fotoImagenNueva);
}


int main(int argc, char* argv[])
{
    char *fileName;
    float lambda;
    int fr=0;
    clock_t init, final;
    init = clock();

    if (argc != 3 && argc != 4)
    {
        cout << "Cantidad de parametros erronea" << endl;
        cout << "Para reducir el ruido:" << endl;
        cout << "   ./main imagenes/64x64/blond.pgm lambda" << endl << endl;
        cout << "Para reducir el ruido y la imagen:" << endl;
        cout << "   ./main imagenes/64x64/blond.pgm lambda factor_reduccion" << endl;
    }
    else
    {
        if (argc == 3)
        {
            fileName = argv[1];
            lambda = atof(argv[2]);

            imagen = fopen(fileName, "r");

            cout << "Lambda: " << lambda << endl;
            cout << "Abrimos el archivo: " << fileName << endl;
            
            sacarRuido(imagen,lambda);

            psnr = calcPSNR(imagen,imagenNueva);
            cout << "PSNR: " << psnr << endl;

            fclose(imagen);
            fclose(imagenNueva);
                                            cout << "Terminaabbbnnnnnnnnnnnnnnnnnnnnaao." << endl << endl;

        }
        else
        {
            fileName = argv[1];
            lambda = atof(argv[2]);
            fr = atoi(argv[3]);

            /// Abrimos la imagen a reducir de tamaño.
            FILE * imagenAReducir;
            imagenAReducir = fopen(fileName, "r");

            cout << "Lambda: " << lambda << endl;
            cout << "Factor reduccion: " << fr << endl << endl;
            cout << "Abrimos el archivo: " << fileName << endl;

            /// Aplicamos la reduccion de tamaño.
            subMuestreo(imagenAReducir, fr);

            fclose(imagenAReducir);

            /// Abrimos la imagen a filtrar.
            FILE * imagenAFiltrar = fopen("./salidaSubMuestreo.pgm", "r");

            cout << "Abrimos el archivo: " << "./salidaSubMuestreo.pgm" << endl;

            /// Aplicamos la reduccion de ruido.
            sacarRuido(imagenAFiltrar, lambda);

            fclose(imagenAFiltrar);

            /// Abrimos la imagen a ampliar.
            FILE * imagenFiltrada = fopen("./ImagenFiltrada.pgm", "r");
            cout << "Abrimos el archivo: " << "./ImagenFiltrada.pgm" << endl;

            /// Aplicamos la ampliacion de tamaño.
            sobreMuestreo(imagenFiltrada, fr);

            fclose(imagenFiltrada);

            psnr = calcPSNR(imagen,imagenNueva);
            cout << "PSNR: " << psnr << endl;
                                cout << "Terminzzzzzzzzzzzzzzzzzzzzzzzzzzaaao." << endl << endl;

            fclose(imagen);
            fclose(imagenNueva);
        }
                                cout << "Terminaabbbbbbbbbbbbbbbbbaaaao." << endl << endl;

    }
    ofstream pepe;
    pepe.open("./RESULTADOS.txt",ios::app);
    final=clock()-init;
    cout<<"tiempo: "<<(double)final / ((double)CLOCKS_PER_SEC)<<endl<<endl;
    pepe<<"Archivo: "<<fileName<<"\t Lambda: "<<(float)lambda<<"\t Fr: "<<fr<<"\t tiempo: "<<(double)final / ((double)CLOCKS_PER_SEC)<<"\t PSNR: "<<psnr<<endl;
    return 0;
}




/*
1 3 0 5 0 0 0 0 0
2 7 8 0 62 0 0 0 0
0 7 6 9 0 5 0 0 0
12 0 2 5 4 0 2 0 0
0 83 0 4 1 2 0 7 0
0 0 7 0 5 6 78 0 35
0 0 0 6 0 8 72 2 0
0 0 0 0 2 0 32 86 23
0 0 0 0 0 12 0 91 12
*/
